package com.xmtlxx.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.tengbo.PushDatasUtil;
import com.xmtlxx.common.tengbo.vo.StoreModelsVo;
import com.xmtlxx.common.utils.JsonUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.utils.TreeBuildUtils;
import com.xmtlxx.wms.domain.Store;
import com.xmtlxx.wms.domain.bo.StoreBo;
import com.xmtlxx.wms.domain.vo.StoreVo;
import com.xmtlxx.wms.mapper.StoreMapper;
import com.xmtlxx.wms.service.IStoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmtlxx.system.mapper.SysAreaMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 仓库Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-08-15
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class StoreServiceImpl implements IStoreService {

    private final StoreMapper baseMapper;

    private final SysAreaMapper areaMapper;


    /**
     * 查询仓库
     *
     * @param id 仓库主键
     * @return 仓库
     */
    @Override
    public StoreVo queryById(String id){
        //return baseMapper.selectVoById(id);
        return baseMapper.selectStoreVoByID(id);
    }

    @Override
    public StoreVo queryByDeptId(Long deptId) {
        return baseMapper.selectStoreVoByDeptID(deptId);
    }

    /**
     * 查询仓库列表
     *
     * @param bo 仓库
     * @return 仓库
     */
    @Override
    public TableDataInfo<StoreVo> queryPageList(StoreBo bo, PageQuery pageQuery) {
       // LambdaQueryWrapper<Store> lqw = buildQueryWrapper(bo);
       // Page<StoreVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Page<StoreVo> result = baseMapper.selectPageStoreList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询仓库列表
     *
     * @param bo 仓库
     * @return 仓库
     */
    @Override
    public List<StoreVo> queryList(StoreBo bo) {
       // LambdaQueryWrapper<Store> lqw = buildQueryWrapper(bo);
       // return baseMapper.selectVoList(lqw);
        return baseMapper.selectStoreList(bo);
    }

    /**
     * 查询仓库列表
     *
     * @param bo 仓库
     * @return 仓库
     */
    @Override
    public List<StoreVo> queryListAll(StoreBo bo) {
        // LambdaQueryWrapper<Store> lqw = buildQueryWrapper(bo);
        // return baseMapper.selectVoList(lqw);
        return baseMapper.selectStoreListAll(bo);
    }

    @Override
    public List<StoreVo> treeStoreList(StoreBo store) {
        return baseMapper.treeStoreList(store);
    }

    @Override
    public List<StoreVo> queryStoreList(StoreBo store) {
//        List<StoreVo> storeVos = baseMapper.selectVoList(new LambdaQueryWrapper<Store>()
//            .like(Store::getName,"综合仓")
//            .or()
//            .like(Store::getName,"车辆仓"));
        return baseMapper.selectStoreListAll(store);
    }

    private LambdaQueryWrapper<Store> buildQueryWrapper(StoreBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Store> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), Store::getName, bo.getName());
        lqw.eq(bo.getDeptId() != null, Store::getDeptId, bo.getDeptId());
        lqw.eq(bo.getUserId() != null, Store::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getProvinceCode()), Store::getProvinceCode, bo.getProvinceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCityCode()), Store::getCityCode, bo.getCityCode());
        lqw.eq(StringUtils.isNotBlank(bo.getAreaCode()), Store::getAreaCode, bo.getAreaCode());
        lqw.eq(StringUtils.isNotBlank(bo.getParentId()), Store::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Store::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getDelFlag()), Store::getDelFlag, bo.getDelFlag());
        return lqw;
    }

    /**
     * 新增仓库
     *
     * @param bo 仓库
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(StoreBo bo) {
        Store add = BeanUtil.toBean(bo, Store.class);
        validEntityBeforeSave(add);

        //填充UUID
        add.setId(IdUtil.simpleUUID());
        add.setDelFlag("0");
        add.setStatus("0");
        if(StringUtils.isNotBlank(bo.getProvinceCode())){
            add.setProvince(areaMapper.selectVoById(bo.getProvinceCode()).getAreaName());
        }
        if(StringUtils.isNotBlank(bo.getCityCode())){
            add.setCity(areaMapper.selectVoById(bo.getCityCode()).getAreaName());
        }
        if(StringUtils.isNotBlank(bo.getAreaCode())){
            add.setArea(areaMapper.selectVoById(bo.getAreaCode()).getAreaName());
        }

        if(!StringUtils.isEmpty(add.getParentId())){
            Store info = baseMapper.selectById(add.getParentId());
            add.setAncestors(info.getAncestors()+ "," + add.getParentId());
        }else{
           add.setAncestors(add.getParentId());
        }

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        pushStoreDatas(add.getId());
        return flag;
    }

    public void pushStoreDatas(String id){
        try{
            StoreVo vo = baseMapper.selectStoreVoByID(id);
            StoreModelsVo data = new StoreModelsVo();
            data.setApi("warehouse");
            data.setData(vo);
            log.info("PushStoreDatas Datas = >{}", JsonUtils.toJsonString(data));
            PushDatasUtil.addTask("warehouse",data);
        }catch (Exception e){
            e.printStackTrace();
            log.error("PushStoreDatas Error = >{}",e.getMessage());
        }
    }

    /**
     * 修改仓库
     *
     * @param bo 仓库
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(StoreBo bo) {
        Store update = BeanUtil.toBean(bo, Store.class);
        validEntityBeforeSave(update);
        if(StringUtils.isNotBlank(bo.getProvinceCode())){
            update.setProvince(areaMapper.selectVoById(bo.getProvinceCode()).getAreaName());
        }
        if(StringUtils.isNotBlank(bo.getCityCode())){
            update.setCity(areaMapper.selectVoById(bo.getCityCode()).getAreaName());
        }
        if(StringUtils.isNotBlank(bo.getAreaCode())){
            update.setArea(areaMapper.selectVoById(bo.getAreaCode()).getAreaName());
        }
        if(!StringUtils.isEmpty(bo.getParentId())){
            Store newParent = baseMapper.selectById(bo.getParentId());
            Store oldClassify = baseMapper.selectById(bo.getId());
            if (ObjectUtil.isNotNull(newParent) && ObjectUtil.isNotNull(oldClassify)) {
                String newAncestors = newParent.getAncestors() + "," + newParent.getId();
                String oldAncestors = oldClassify.getAncestors();
                update.setAncestors(newAncestors);
                updateClassifyChildren(update.getId(), newAncestors, oldAncestors);
            }
        }
        boolean flag = baseMapper.updateById(update) > 0;
        pushStoreDatas(update.getId());
        return flag;
    }

    /**
     * 修改子元素关系
     *
     * @param id       被修改的分类ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateClassifyChildren(String id, String newAncestors, String oldAncestors) {
        List<Store> children = baseMapper.selectList(new LambdaQueryWrapper<Store>()
            .apply("find_in_set({0},ancestors)", id));
        for (Store child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            baseMapper.updateStoreChildren(children);
        }
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(Store entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除仓库
     *
     * @param ids 需要删除的仓库主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<Tree<String>> buildStoreTreeSelect(List<StoreVo> items) {
        if (CollUtil.isEmpty(items)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(items, (store, tree) ->
            tree.setId(store.getId())
                .setParentId(store.getParentId())
                .setName(store.getName())
                .setWeight(store.getId()));
    }

    @Override
    public List<String> selectAncestorsByUserId(Long userId) {
        List<Store> stores = baseMapper.selectList(new LambdaQueryWrapper<Store>().eq(Store::getUserId,userId));
        List<String> result = new ArrayList<>();
        if(stores != null && stores.size() > 0){
            for(Store store : stores){
                result.add(store.getId());
                String ancestores = store.getAncestors();
                if(StringUtils.isNotEmpty(ancestores)){
                    String[] ancestor = ancestores.split(",");
                    for(String storeId : ancestor){
                        if(StringUtils.isNotEmpty(storeId) && !storeId.toLowerCase().equals("null")){
                            result.add(storeId);
                        }
                    }
                }
            }
        }
        return result;
    }
}
